﻿using System;
using System.Collections.Generic;
using System.Text;

namespace IOPerformanceVerifier
{
    public class ThreadConfigutation
    {
        private string _diskTestName;
        private bool _isDiskTestNameSet;
        private string _logicalDriveLetter;
        private bool _isLogicalDriveLetterSet;
        private string _dataFilePlacement;
        private bool _isDataFilePlacementSet;
        private float _pressureMultiplier;
        private bool _isPressureMultiplierSet;
        private int _numberOfThreads;
        private bool _isNumberOfThreadsSet;
        private bool _nonBufferedWrite;
        private bool _isNonBufferedWriteSet;
        private bool _blockWrite;
        private bool _isBlockWriteSet;
        private int _blockSize;
        private bool _isBlockSizeSet;
        private float _readPerUnit;
        private bool _isReadPerUnitSet;
        private float _writePerUnit;
        private bool _isWritePerUnitSet;
        private float _readsPerSecond;
        private bool _isReadsPerSecondSet;
        private float _writesPerSecond;
        private bool _isWritesPerSecondSet;
        private string _unitName;
        private bool _isUnitNameSet;
        private float _unitFactor;
        private bool _isUnitFactorSet;
        private int _fileSize;
        private bool _isFileSizeSet;
        private bool _sequentialIO;
        private bool _isSequentialIOSet;
        private bool _randomIODistributed;
        private bool _isRandomIODistributedSet;
        private IOThreadType _threadType = IOThreadType.NotSet;
        private int _threadNumber = -1;

        public string DiskTestName
        {
            get
            { 
                return _diskTestName; 
            }
            set 
            {
                _isDiskTestNameSet = true;
                _diskTestName = value;
            }
        }

        public string InternalDiskTestName
        {
            get
            {
                return _diskTestName+ "_" + _threadType.ToString() + "_" + _threadNumber;
            }
        }

        public bool IsDiskTestNameSet
        {
            get 
            {
                return _isDiskTestNameSet;
            }
        }

        public string LogicalDriveLetter 
        { 
            get
            {
                return _logicalDriveLetter;
            }
            set
            {
                _isLogicalDriveLetterSet = true;
                _logicalDriveLetter = value;
            }
        }

        public bool IsLogicalDriveLetterSet
        {
            get
            {
                return _isLogicalDriveLetterSet;
            }
        }

        public string DataFilePlacement
        {
            get
            {
                return _dataFilePlacement;
            }
            set
            {
                _isDataFilePlacementSet = true;
                _dataFilePlacement = value;
            }
        }

        public bool IsDataFilePlacementSet
        {
            get
            {
                return _isDataFilePlacementSet;
            }
        }

        public float PressureMultiplier
        {
            get
            {
                return _pressureMultiplier;
            }
            set
            {
                _isPressureMultiplierSet = true;
                _pressureMultiplier = value;
            }
        }

        public bool IsPressureMultiplierSet
        {
            get
            {
                return _isPressureMultiplierSet;
            }
        }

        public int NumberOfThreads
        {
            get
            {
                return _numberOfThreads;
            }
            set
            {
                _isNumberOfThreadsSet = true;
                _numberOfThreads = value;
            }
        }

        public bool IsNumberOfThreadsSet
        {
            get
            {
                return _isNumberOfThreadsSet;
            }
        }

        public bool NonBufferedWrite
        {
            get
            {
                return _nonBufferedWrite;
            }
            set
            {
                _isNonBufferedWriteSet = true;
                _nonBufferedWrite = value;
            }
        }

        public bool IsNonBufferedWriteSet
        {
            get
            {
                return _isNonBufferedWriteSet;
            }
        }

        public bool BlockWrite
        {
            get
            {
                return _blockWrite;
            }
            set
            {
                _isBlockWriteSet = true;
                _blockWrite = value;
            }
        }

        public bool IsBlockWriteSet
        {
            get 
            { 
                return _isBlockWriteSet; 
            }
        }

        public int BlockSize
        {
            get
            {
                return _blockSize;
            }
            set
            {
                _isBlockSizeSet = true;
                _blockSize = value;
            }
        }

        public bool IsBlockSizeSet
        {
            get
            {
                return _isBlockSizeSet;
            }
        }

        public float ReadPerUnit
        {
            get
            {
                return _readPerUnit;
            }
            set
            {
                _isReadPerUnitSet = true;
                _readPerUnit = value;
            }
        }

        public bool IsReadPerUnitSet
        {
            get
            {
                return _isReadPerUnitSet;
            }
        }

        public float WritePerUnit
        {
            get
            {
                return _writePerUnit;
            }
            set
            {
                _isWritePerUnitSet = true;
                _writePerUnit = value;
            }
        }

        public bool IsWritePerUnitSet
        {
            get
            {
                return _isWritePerUnitSet;
            }
        }

        public float ReadsPerSecond
        {
            get
            {
                return _readsPerSecond;
            }
            set
            {
                _isReadsPerSecondSet = true;
                _readsPerSecond = value;
            }
        }

        public bool IsReadsPerSecondSet
        {
            get
            {
                return _isReadsPerSecondSet;
            }
        }

        public float WritesPerSecond
        {
            get
            {
                return _writesPerSecond;
            }
            set
            {
                _isWritesPerSecondSet = true;
                _writesPerSecond = value;
            }
        }

        public bool IsWritesPerSecondSet
        {
            get
            {
                return _isWritesPerSecondSet;
            }
        }

        public string UnitName
        {
            get
            {
                return _unitName;
            }
            set
            {
                _isUnitNameSet = true;
                _unitName = value;
            }
        }

        public bool IsUnitNameSet
        {
            get
            {
                return _isUnitNameSet;
            }
        }

        public float UnitFactor
        {
            get
            {
                return _unitFactor;
            }
            set
            {
                _isUnitFactorSet = true;
                _unitFactor = value;
            }
        }

        public bool IsUnitFactorSet
        {
            get
            {
                return _isUnitFactorSet;
            }
        }

        public int FileSize
        {
            get
            {
                return _fileSize;
            }
            set
            {
                _isFileSizeSet = true;
                _fileSize = value;

            }
        }

        public bool IsFileSizeSet
        {
            get
            {
                return _isFileSizeSet;
            }
        }

        public bool SequentialIO
        {
            get
            {
                return _sequentialIO;
            }
            set
            {
                _isSequentialIOSet = true;
                _sequentialIO = value;
            }
        }

        public bool IsSequentialIOSet
        {
            get
            {
                return _isSequentialIOSet;
            }
        }

        public bool RandomIODistributed
        {
            get
            {
                return _randomIODistributed;
            }
            set
            {
                _isRandomIODistributedSet = true;
                _randomIODistributed = value;
            }
        }
        public bool IsRandomIODistributedSet
        {
            get
            {
                return _isRandomIODistributedSet;
            }
        }
        public string AbsoluteFilePath 
        {
            get
            {
                return _logicalDriveLetter + ":" + _dataFilePlacement + "\\" + makeFileName(_diskTestName) + ".iov";
            }
        }

        private string makeFileName(string diskTestName)
        {
            return InternalDiskTestName.Replace(" ", "");
        }

        public IOThreadType ThreadType
        {
            get
            {
                return _threadType;
            }
            set
            {
                _threadType = value;
            }
        }

        public int ThreadNumber
        {
            get
            {
                return _threadNumber;
            }
            set
            {
                _threadNumber = value;
            }
        }

        public int InternalFileSize
        {
            get
            {
                return (int) Math.Ceiling( (_fileSize *1.0)/_numberOfThreads);
            }
        }

        public float InternalReadPerUnit
        {
            get
            {
                return (int)Math.Ceiling((_readPerUnit * 1.0) / _numberOfThreads);
            }
        }

        public float InternalWritePerUnit
        {
            get
            {
                return (int)Math.Ceiling((_writePerUnit * 1.0) / _numberOfThreads);
            }
        }

        public ThreadConfigutation cloneConfiguration()
        {
            ThreadConfigutation clonedThreadConfiguration = new ThreadConfigutation();
            if (_isDiskTestNameSet)
            {
                clonedThreadConfiguration.DiskTestName = _diskTestName;
            }
            if (_isLogicalDriveLetterSet)
            {
                clonedThreadConfiguration.LogicalDriveLetter = _logicalDriveLetter;
            }
            if (_isDataFilePlacementSet)
            {
                clonedThreadConfiguration.DataFilePlacement = _dataFilePlacement;
            }
            if (_isPressureMultiplierSet)
            {
                clonedThreadConfiguration.PressureMultiplier = _pressureMultiplier;
            }
            if (_isNumberOfThreadsSet)
            {
                clonedThreadConfiguration.NumberOfThreads = _numberOfThreads;
            }
            if (_isNonBufferedWriteSet)
            {
                clonedThreadConfiguration.NonBufferedWrite = _nonBufferedWrite;
            }
            if (_isBlockWriteSet)
            {
                clonedThreadConfiguration.BlockWrite = _blockWrite;
            }
            if (_isBlockSizeSet)
            {
                clonedThreadConfiguration.BlockSize = _blockSize;
            }
            if (_isReadPerUnitSet)
            {
                clonedThreadConfiguration.ReadPerUnit = _readPerUnit;
            }
            if (_isWritePerUnitSet)
            {
                clonedThreadConfiguration.WritePerUnit = _writePerUnit;
            }
            if (_isReadsPerSecondSet)
            {
                clonedThreadConfiguration.ReadsPerSecond = _readsPerSecond;
            }
            if (_isWritesPerSecondSet)
            {
                clonedThreadConfiguration.WritesPerSecond = _writesPerSecond;
            }
            if (_isUnitNameSet)
            {
                clonedThreadConfiguration.UnitName = _unitName;
            }
            if (_isUnitFactorSet)
            {
                clonedThreadConfiguration.UnitFactor = _unitFactor;
            }
            if (_isFileSizeSet)
            {
                clonedThreadConfiguration.FileSize = _fileSize;
            }
            if (_isSequentialIOSet)
            {
                clonedThreadConfiguration.SequentialIO = _sequentialIO;
            }
            if (_isRandomIODistributedSet)
            {
                clonedThreadConfiguration.RandomIODistributed = _randomIODistributed;
            }
            return clonedThreadConfiguration;
        }
    }
}
